Asinxron iteratsiya va holat mashinalarini tatbiq qilish kabi ilg'or JavaScript generator patternlarini o'rganing. Tozaroq va qo'llab-quvvatlash osonroq kod yozishni o'rganing.
JavaScript Generatorlari: Asinxron Iteratsiya va Holat Mashinalari uchun Ilg'or Patternlar
JavaScript generatorlari - bu iteratorlarni yanada qisqa va o'qilishi oson tarzda yaratishga imkon beruvchi kuchli xususiyatdir. Ular ko'pincha ketma-ketliklarni yaratishning oddiy misollari bilan tanishtirilsa-da, ularning haqiqiy salohiyati asinxron iteratsiya va holat mashinalarini tatbiq qilish kabi ilg'or patternlarda yotadi. Ushbu blog postida ushbu ilg'or patternlar chuqur o'rganilib, loyihalaringizda generatorlardan unumli foydalanishga yordam beradigan amaliy misollar va foydali maslahatlar taqdim etiladi.
JavaScript Generatorlarini Tushunish
Ilg'or patternlarga sho'ng'ishdan oldin, keling, JavaScript generatorlarining asoslarini tezda takrorlab olaylik.
Generator - bu to'xtatib turilishi va qayta ishga tushirilishi mumkin bo'lgan maxsus turdagi funksiyadir. Ular function* sintaksisi yordamida aniqlanadi va bajarilishni to'xtatib, qiymat qaytarish uchun yield kalit so'zidan foydalanadi. next() metodi bajarilishni davom ettirish va keyingi qaytarilgan qiymatni olish uchun ishlatiladi.
Oddiy Misol
Bu yerda sonlar ketma-ketligini qaytaradigan generatorning oddiy misoli keltirilgan:
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const generator = numberGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
Generatorlar yordamida Asinxron Iteratsiya
Generatorlardan foydalanishning eng jozibali holatlaridan biri bu asinxron iteratsiyadir. Bu sizga callback'lar yoki Promise'larning murakkabliklaridan qochib, asinxron ma'lumotlar oqimlarini ketma-ket va o'qilishi osonroq tarzda qayta ishlashga imkon beradi.
An'anaviy Asinxron Iteratsiya (Promise'lar)
Bir nechta API nuqtalaridan ma'lumotlarni olish va natijalarni qayta ishlash kerak bo'lgan vaziyatni ko'rib chiqing. Generatorlarsiz, siz Promise'lar va async/await dan quyidagicha foydalanishingiz mumkin:
async function fetchData() {
const urls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/data3'
];
for (const url of urls) {
try {
const response = await fetch(url);
const data = await response.json();
console.log(data); // Ma'lumotlarni qayta ishlash
} catch (error) {
console.error('Ma\'lumotlarni olishda xatolik:', error);
}
}
}
fetchData();
Ushbu yondashuv ishlasa-da, murakkabroq asinxron operatsiyalar bilan ishlaganda u haddan tashqari ko'p so'zli va boshqarish qiyin bo'lib qolishi mumkin.
Generatorlar va Asinxron Iteratorlar bilan Asinxron Iteratsiya
Asinxron iteratorlar bilan birlashtirilgan generatorlar yanada oqlangan yechimni taqdim etadi. Asinxron iterator - bu value va done xususiyatlariga ega obyekt bilan yakunlanadigan Promise qaytaruvchi next() metodini ta'minlaydigan obyektdir. Generatorlar osongina asinxron iteratorlarni yaratishi mumkin.
async function* asyncDataFetcher(urls) {
for (const url of urls) {
try {
const response = await fetch(url);
const data = await response.json();
yield data;
} catch (error) {
console.error('Ma\'lumotlarni olishda xatolik:', error);
yield null; // Yoki xatolikni kerak bo'lganda qayta ishlang
}
}
}
async function processAsyncData() {
const urls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/data3'
];
const dataStream = asyncDataFetcher(urls);
for await (const data of dataStream) {
if (data) {
console.log(data); // Ma'lumotlarni qayta ishlash
} else {
console.log('Yuklash paytida xatolik');
}
}
}
processAsyncData();
Ushbu misolda, asyncDataFetcher har bir URL manzildan olingan ma'lumotlarni qaytaradigan asinxron generatordir. processAsyncData funksiyasi ma'lumotlar oqimi bo'ylab iteratsiya qilish uchun for await...of tsiklidan foydalanadi va har bir elementni mavjud bo'lishi bilan qayta ishlaydi. Ushbu yondashuv asinxron operatsiyalarni ketma-ket bajaradigan tozaroq va o'qilishi osonroq kodga olib keladi.
Generatorlar bilan Asinxron Iteratsiyaning Afzalliklari
- O'qilishi osonligi: Kod sinxron tsiklga o'xshab o'qiladi, bu esa bajarilish oqimini tushunishni osonlashtiradi.
- Xatoliklarni qayta ishlash: Xatoliklarni qayta ishlash generator funksiyasi ichida markazlashtirilishi mumkin.
- Kompozitsionlik: Asinxron generatorlarni osongina birlashtirish va qayta ishlatish mumkin.
- Qayta bosimni boshqarish (Backpressure): Generatorlar qayta bosimni amalga oshirish uchun ishlatilishi mumkin, bu esa iste'molchining ishlab chiqaruvchi tomonidan haddan tashqari yuklanishining oldini oladi.
Haqiqiy hayotdan misollar
- Oqimli ma'lumotlar: Katta hajmdagi fayllarni yoki API'lardan real vaqtdagi ma'lumotlar oqimlarini qayta ishlash. Moliya institutidan katta CSV faylini qayta ishlashni, yangilangan aksiyalar narxlarini tahlil qilishni tasavvur qiling.
- Ma'lumotlar bazasi so'rovlari: Ma'lumotlar bazasidan katta hajmdagi ma'lumotlar to'plamlarini qismlarga bo'lib olish. Masalan, millionlab yozuvlarni o'z ichiga olgan ma'lumotlar bazasidan mijozlar yozuvlarini olish, xotira muammolarini oldini olish uchun ularni partiyalarga bo'lib qayta ishlash.
- Real vaqtdagi chat ilovalari: Websocket ulanishidan keladigan xabarlarni qayta ishlash. Global chat ilovasini ko'rib chiqing, bu yerda xabarlar doimiy ravishda qabul qilinadi va turli vaqt zonalaridagi foydalanuvchilarga ko'rsatiladi.
Generatorlar bilan Holat Mashinalari
Generatorlarning yana bir kuchli qo'llanilishi holat mashinalarini amalga oshirishdir. Holat mashinasi - bu kiruvchi ma'lumotlarga asoslanib turli holatlar o'rtasida o'tadigan hisoblash modelidir. Generatorlar holat o'tishlarini aniq va qisqa tarzda belgilash uchun ishlatilishi mumkin.
An'anaviy Holat Mashinasi Implementatsiyasi
An'anaga ko'ra, holat mashinalari o'zgaruvchilar, shartli operatorlar va funksiyalar kombinatsiyasi yordamida amalga oshiriladi. Bu murakkab va qo'llab-quvvatlash qiyin bo'lgan kodga olib kelishi mumkin.
const STATE_IDLE = 'IDLE';
const STATE_LOADING = 'LOADING';
const STATE_SUCCESS = 'SUCCESS';
const STATE_ERROR = 'ERROR';
let currentState = STATE_IDLE;
let data = null;
let error = null;
async function fetchDataStateMachine(url) {
switch (currentState) {
case STATE_IDLE:
currentState = STATE_LOADING;
try {
const response = await fetch(url);
data = await response.json();
currentState = STATE_SUCCESS;
} catch (e) {
error = e;
currentState = STATE_ERROR;
}
break;
case STATE_LOADING:
// Yuklash paytida kiritishni e'tiborsiz qoldirish
break;
case STATE_SUCCESS:
// Ma'lumotlar bilan nimadir qilish
console.log('Ma\'lumotlar:', data);
currentState = STATE_IDLE; // Qayta o'rnatish
break;
case STATE_ERROR:
// Xatolikni qayta ishlash
console.error('Xatolik:', error);
currentState = STATE_IDLE; // Qayta o'rnatish
break;
default:
console.error('Noto\'g\'ri holat');
}
}
fetchDataStateMachine('https://api.example.com/data');
Ushbu misol switch operatoridan foydalangan holda oddiy ma'lumotlarni yuklash holat mashinasini namoyish etadi. Holat mashinasining murakkabligi oshgani sayin, ushbu yondashuvni boshqarish tobora qiyinlashib boradi.
Generatorlar bilan Holat Mashinalari
Generatorlar holat mashinalarini amalga oshirishning yanada oqlangan va tuzilgan usulini taqdim etadi. Har bir yield ifodasi holat o'tishini anglatadi va generator funksiyasi holat mantig'ini o'z ichiga oladi.
function* dataFetchingStateMachine(url) {
let data = null;
let error = null;
try {
// HOLAT: YUKLANMOQDA
const response = yield fetch(url);
data = yield response.json();
// HOLAT: MUVAFFAQIYATLI
yield data;
} catch (e) {
// HOLAT: XATOLIK
error = e;
yield error;
}
// HOLAT: BO'SH (MUVAFFAQIYATLI yoki XATOLIKdan keyin bilvosita erishiladi)
return;
}
async function runStateMachine() {
const stateMachine = dataFetchingStateMachine('https://api.example.com/data');
let result = stateMachine.next();
while (!result.done) {
const value = result.value;
if (value instanceof Promise) {
// Asinxron operatsiyalarni qayta ishlash
try {
const resolvedValue = await value;
result = stateMachine.next(resolvedValue); // Hal qilingan qiymatni generatorga qaytarish
} catch (e) {
result = stateMachine.throw(e); // Xatolikni generatorga qaytarish
}
} else if (value instanceof Error) {
// Xatoliklarni qayta ishlash
console.error('Xatolik:', value);
result = stateMachine.next();
} else {
// Muvaffaqiyatli ma'lumotlarni qayta ishlash
console.log('Ma\'lumotlar:', value);
result = stateMachine.next();
}
}
}
runStateMachine();
Ushbu misolda, dataFetchingStateMachine generatori quyidagi holatlarni belgilaydi: YUKLANMOQDA (fetch(url) yield bilan ifodalangan), MUVAFFAQIYATLI (data yield bilan ifodalangan) va XATOLIK (error yield bilan ifodalangan). runStateMachine funksiyasi holat mashinasini boshqaradi, asinxron operatsiyalar va xatolik holatlarini qayta ishlaydi. Ushbu yondashuv holat o'tishlarini aniq va kuzatish oson qiladi.
Generatorlar bilan Holat Mashinalarining Afzalliklari
- O'qilishi osonligi: Kod holat o'tishlarini va har bir holat bilan bog'liq mantig'ini aniq ifodalaydi.
- Inkapsulyatsiya: Holat mashinasi mantig'i generator funksiyasi ichida inkapsulyatsiya qilingan.
- Test qilish imkoniyati: Holat mashinasini generator orqali qadamma-qadam o'tib va kutilgan holat o'tishlarini tasdiqlash orqali osonlikcha sinab ko'rish mumkin.
- Qo'llab-quvvatlash osonligi: Holat mashinasidagi o'zgarishlar generator funksiyasi bilan cheklanadi, bu esa uni qo'llab-quvvatlash va kengaytirishni osonlashtiradi.
Haqiqiy hayotdan misollar
- UI Komponentining Hayot Sikli: UI komponentining turli holatlarini (masalan, yuklash, ma'lumotlarni ko'rsatish, xatolik) boshqarish. Sayohat ilovasidagi xarita komponentini ko'rib chiqing, u xarita ma'lumotlarini yuklash, markerlar bilan xaritani ko'rsatish, xarita ma'lumotlari yuklanmasa xatoliklarni qayta ishlash va foydalanuvchilarga o'zaro ta'sir o'tkazish va xaritani yanada takomillashtirishga imkon berish kabi holatlardan o'tadi.
- Ish Jarayonini Avtomatlashtirish: Bir nechta qadamlar va bog'liqliklarga ega murakkab ish jarayonlarini amalga oshirish. Xalqaro yuk tashish ish jarayonini tasavvur qiling: to'lov tasdiqlanishini kutish, jo'natmani bojxona uchun tayyorlash, jo'natuvchi mamlakatda bojxona rasmiylashtiruvi, yuk tashish, qabul qiluvchi mamlakatda bojxona rasmiylashtiruvi, yetkazib berish, yakunlash. Ushbu qadamlarning har biri bir holatni ifodalaydi.
- O'yinlarni Rivojlantirish: O'yin obyektlarining xatti-harakatlarini ularning joriy holatiga (masalan, bo'sh, harakatlanayotgan, hujum qilayotgan) qarab boshqarish. Global ko'p o'yinchili onlayn o'yindagi sun'iy intellektli dushmanni o'ylab ko'ring.
Generatorlarda Xatoliklarni Qayta Ishlash
Generatorlar bilan ishlaganda, ayniqsa asinxron stsenariylarda xatoliklarni qayta ishlash juda muhim. Xatoliklarni qayta ishlashning ikkita asosiy usuli mavjud:
- Try...Catch Bloklari: Bajarilish paytida yuzaga keladigan xatoliklarni qayta ishlash uchun generator funksiyasi ichida
try...catchbloklaridan foydalaning. throw()Metodi: Generatorga uning hozirda to'xtatilgan nuqtasida xatolik kiritish uchun generator obyektiningthrow()metodidan foydalaning.
Oldingi misollar allaqachon try...catch yordamida xatoliklarni qayta ishlashni namoyish etgan. Keling, throw() metodini o'rganamiz.
function* errorGenerator() {
try {
yield 1;
yield 2;
yield 3;
} catch (error) {
console.error('Xatolik ushlandi:', error);
}
}
const generator = errorGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.throw(new Error('Something went wrong'))); // Xatolik ushlandi: Error: Something went wrong
console.log(generator.next()); // { value: undefined, done: true }
Ushbu misolda, throw() metodi generatorga xatolik kiritadi, bu esa catch bloki tomonidan ushlanadi. Bu sizga generator funksiyasidan tashqarida yuzaga keladigan xatoliklarni qayta ishlashga imkon beradi.
Generatorlardan Foydalanish bo'yicha Eng Yaxshi Amaliyotlar
- Tushunarli Nomlardan Foydalaning: Kodning o'qilishini yaxshilash uchun generator funksiyalaringiz va qaytariladigan qiymatlar uchun tushunarli nomlarni tanlang.
- Generatorlarni Maqsadli Qiling: Generatorlaringizni ma'lum bir vazifani bajarish yoki ma'lum bir holatni boshqarish uchun loyihalashtiring.
- Xatoliklarni To'g'ri Qayta Ishlang: Kutilmagan xatti-harakatlarning oldini olish uchun mustahkam xatoliklarni qayta ishlashni joriy qiling.
- Kodingizni Hujjatlashtiring: Har bir yield ifodasi va holat o'tishining maqsadini tushuntirish uchun izohlar qo'shing.
- Ishlash Unumdorligini Hisobga Oling: Generatorlar ko'plab afzalliklarga ega bo'lsa-da, ularning ishlash unumdorligiga ta'sirini, ayniqsa yuqori unumdorlik talab etiladigan ilovalarda yodda tuting.
Xulosa
JavaScript generatorlari murakkab ilovalarni yaratish uchun ko'p qirrali vositadir. Asinxron iteratsiya va holat mashinalarini amalga oshirish kabi ilg'or patternlarni o'zlashtirib, siz tozaroq, qo'llab-quvvatlash osonroq va samaraliroq kod yozishingiz mumkin. Keyingi loyihangizda generatorlardan foydalaning va ularning to'liq salohiyatini oching.
Har doim loyihangizning o'ziga xos talablarini hisobga olishni va topshiriq uchun mos patternni tanlashni unutmang. Amaliyot va tajriba orqali siz turli xil dasturlash muammolarini hal qilishda generatorlardan mohirona foydalanadigan bo'lasiz.